#!/bin/bash

plain='\033[0m'
info='\033[32m'
error='\033[41;30m'
success='\033[42;30m'
pwd=`pwd`
file=$1

echo -e "
######################################################################
${info}         Configure the Hostname and SSH Authentication ${plain}
${info} Useage: ${plain}
 Create a txt that contains the IP,hostname,username,and password,such as: ${plain}
 192.168.64.100 master root PassWord1
 192.168.64.101 node1 root PassWord2
 192.168.64.102 node2 root PassWord3
 Then,run the script: sh ssh-auth.sh {txt}
${info} Notices: ${plain}The EXPECT package must be installed.
 2022-05-05
######################################################################
"

# 检查文件
if [ ! -f "$file" ]; then echo -e "${error} [ERROR]: File does not exist! ${plain}"; exit 1; fi

# 读取配置文件
IPADDRESS=()
HOSTNAMES=()
USERNAMES=()
PASSWORDS=()
while read line; do
    if [ ! -n "$line" ]; then break 1; fi
	ipaddres=$(echo $line | cut -d " " -f1)
	hostname=$(echo $line | cut -d " " -f2)
	username=$(echo $line | cut -d " " -f3)
	password=$(echo $line | cut -d " " -f4)
	if [ ! -n "$ipaddres" ]; then echo "${error} [ERROR]: File content format error! ${plain}"; exit 1; fi
	if [ ! -n "$hostname" ]; then echo "${error} [ERROR]: File content format error! ${plain}"; exit 1; fi
	if [ ! -n "$username" ]; then echo "${error} [ERROR]: File content format error! ${plain}"; exit 1; fi
	if [ ! -n "$password" ]; then echo "${error} [ERROR]: File content format error! ${plain}"; exit 1; fi
	IPADDRESS[${#IPADDRESS[*]}]=${ipaddres}
	HOSTNAMES[${#HOSTNAMES[*]}]=${hostname}
	USERNAMES[${#USERNAMES[*]}]=${username}
	PASSWORDS[${#PASSWORDS[*]}]=${password}
done < $file

rpm -q expect &>/dev/null
if [ $? != 0 ]; then
yum -y install expect #&>/dev/null
fi
if [ $? != 0 ]; then echo "${error} [ERROR]: Install expect failed! ${plain}"; exit 1; fi

ssh_keygen(){
# 登陆到各个主机上，使用ssh-keygen工具生成公钥和私钥
echo -e "${info} [1/8] Use ssh-keygen to generate key... ${plain}"
for ((i = 0; i < ${#IPADDRESS[@]}; i++)); do
	ipaddres=${IPADDRESS[$i]}
	username=${USERNAMES[$i]}
	hostname=${HOSTNAMES[$i]}
	password=${PASSWORDS[$i]}

	echo "IP:${ipaddres}"		
	expect <<EOF
		spawn ssh ${username}@${ipaddres} "rm -rf  ~/.ssh; ssh-keygen -t rsa -N '' -f ~/.ssh/id_rsa -q"
		expect {
			"yes/no" { send "yes\n";exp_continue}
			"assword" { send "${password}\n"}
		}
		expect eof 
EOF
done #&>/dev/null
}

scp_public_keys(){
# 将每个主机上的id_rsa.pub拷贝到本地，并汇总至authorized_keys
echo -e "${info} [2/8] Copy remote public_keys to local... ${plain}"
for ((i = 0; i < ${#IPADDRESS[@]}; i++)); do
	ipaddres=${IPADDRESS[$i]}
	username=${USERNAMES[$i]}
	hostname=${HOSTNAMES[$i]}
	password=${PASSWORDS[$i]}

 	echo "IP:${ipaddres}" 
	TMP_FILE="$pwd/id_rsa.pub.${ipaddres}"
	expect <<EOF
		spawn scp ${username}@${ipaddres}:~/.ssh/id_rsa.pub  $TMP_FILE
		expect {
			"yes/no" { send "yes\n";exp_continue}
			"assword" { send "${password}\n"}
		}
		expect eof 
EOF
	cat $TMP_FILE >> ~/.ssh/authorized_keys && rm -f $TMP_FILE
done #&>/dev/null
}

scp_authorized_keys(){
# 将本地authorized_keys分发到每个主机上
echo -e "${info} [3/8] Send local authorized_keys to each host... ${plain}"
for ((i = 0; i < ${#IPADDRESS[@]}; i++)); do
	ipaddres=${IPADDRESS[$i]}
	username=${USERNAMES[$i]}
	hostname=${HOSTNAMES[$i]}
	password=${PASSWORDS[$i]}

	echo "IP:${ipaddres}"
	if [ "$username" == "root" ]; then
		CMD="scp /root/.ssh/authorized_keys root@${ipaddres}:/root/.ssh/authorized_keys"
		else
		CMD="scp /home/$username/.ssh/authorized_keys $username@${ipaddres}:/home/$username/.ssh/authorized_keys"
	fi
	expect <<EOF
		spawn $CMD
		expect {
			"yes/no" { send "yes\n";exp_continue}
			"assword" { send "${password}\n"}
		}
		expect eof 
EOF
done #&>/dev/null
}

scp_known_hosts(){
# 将本地known_hosts分发到每个主机上
echo -e "${info} [4/8] Send local known_hosts to each host... ${plain}"
for ((i = 0; i < ${#IPADDRESS[@]}; i++)); do
	ipaddres=${IPADDRESS[$i]}
	username=${USERNAMES[$i]}
	hostname=${HOSTNAMES[$i]}
	password=${PASSWORDS[$i]}

	echo "IP:${ipaddres}"
	scp ~/.ssh/known_hosts ${username}@${ipaddres}:~/.ssh/known_hosts
done #&>/dev/null
}

generate_hosts_template(){
# 生成hosts模板
echo -e "${info} [5/8] Generate hosts template... ${plain}"
cat $file |awk {'print $1 " " $2'} > hosts.template
}

scp_hosts_template(){
# 将hosts模板分发到每个主机上
echo -e "${info} [6/8] Send hosts.template to each host... ${plain}"
for ((i = 0; i < ${#IPADDRESS[@]}; i++)); do
	ipaddres=${IPADDRESS[$i]}
	username=${USERNAMES[$i]}
	hostname=${HOSTNAMES[$i]}
	password=${PASSWORDS[$i]}

	echo "IP:${ipaddres} hostname:${hostname}"
	scp hosts.template ${username}@${ipaddres}:/etc/hosts.template
	ssh ${username}@${ipaddres} "cat /etc/hosts.template >> /etc/hosts && rm -rf /etc/hosts.template && hostnamectl set-hostname --static ${hostname}"
done #&>/dev/null
}

ssh_hostname(){
# ssh连接到所有hostname，生成hostname的known_hosts记录
echo -e "${info} [7/8] SSH to each host with the hostname... ${plain}"
for ((i = 0; i < ${#IPADDRESS[@]}; i++)); do
	ipaddres=${IPADDRESS[$i]}
	username=${USERNAMES[$i]}
	hostname=${HOSTNAMES[$i]}
	password=${PASSWORDS[$i]}

	echo "IP:${ipaddres} hostname:${hostname}"
	expect <<EOF
			spawn ssh ${username}@${hostname} "exit"
			expect {
				"yes/no" { send "yes\n";exp_continue}
			}
			expect eof 
EOF
done #&>/dev/null
}

scp_known_hosts_again(){
# 再次将本地known_hosts分发到每个主机上
echo -e "${info} [8/8] Send local known_hosts to each host again... ${plain}"
for ((i = 0; i < ${#IPADDRESS[@]}; i++)); do
	ipaddres=${IPADDRESS[$i]}
	username=${USERNAMES[$i]}
	hostname=${HOSTNAMES[$i]}
	password=${PASSWORDS[$i]}

	echo "IP:${ipaddres} hostname:${hostname}"
	scp ~/.ssh/known_hosts ${username}@${hostname}:~/.ssh/known_hosts
done #&>/dev/null
echo -e "${success} [INFO]:SSH Auth SUCCESS! ${plain}"
}


ssh_keygen
scp_public_keys
scp_authorized_keys
scp_known_hosts
generate_hosts_template
scp_hosts_template
ssh_hostname
scp_known_hosts_again
